﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using DailyPoetryX.Views;
using Xamarin.Forms;

namespace DailyPoetryX.Services {
    /// <summary>
    /// 根导航服务。
    /// </summary>
    /// <seealso cref="GalaSoft.MvvmLight.Views.INavigationService"/>
    public interface IRootNavigationService {
        /// <summary>
        /// Instructs the navigation service to display a new page
        /// corresponding to the given key. Depending on the platforms,
        /// the navigation service might have to be configured with a
        /// key/page list.
        /// </summary>
        /// <param name="pageKey">The key corresponding to the page
        /// that should be displayed.</param>
        Task NavigateToAsync(string pageKey);

        /// <summary>
        /// Instructs the navigation service to display a new page
        /// corresponding to the given key, and passes a parameter
        /// to the new page.
        /// Depending on the platforms, the navigation service might 
        /// have to be Configure with a key/page list.
        /// </summary>
        /// <param name="pageKey">The key corresponding to the page
        /// that should be displayed.</param>
        /// <param name="parameter">The parameter that should be passed
        /// to the new page.</param>
        Task NavigateToAsync(string pageKey, object parameter);
    }

    /// <summary>
    /// 内容导航服务
    /// </summary>
    /// <seealso cref="GalaSoft.MvvmLight.Views.INavigationService"/>
    public interface IContentNavigationService {
        /// <summary>
        /// Instructs the navigation service to display a new page
        /// corresponding to the given key. Depending on the platforms,
        /// the navigation service might have to be configured with a
        /// key/page list.
        /// </summary>
        /// <param name="pageKey">The key corresponding to the page
        /// that should be displayed.</param>
        Task NavigateToAsync(string pageKey);

        /// <summary>
        /// Instructs the navigation service to display a new page
        /// corresponding to the given key, and passes a parameter
        /// to the new page.
        /// Depending on the platforms, the navigation service might 
        /// have to be Configure with a key/page list.
        /// </summary>
        /// <param name="pageKey">The key corresponding to the page
        /// that should be displayed.</param>
        /// <param name="parameter">The parameter that should be passed
        /// to the new page.</param>
        Task NavigateToAsync(string pageKey, object parameter);
    }

    /// <summary>
    /// 根导航服务常量。
    /// </summary>
    public static class RootNavigationServiceConstants {
        /// <summary>
        /// 初始化页。
        /// </summary>
        public static readonly string InitializationPage =
            nameof(Views.InitializationPage);

        /// <summary>
        /// 今日推荐页。
        /// </summary>
        public static readonly string TodayPage = nameof(Views.TodayPage);

        /// <summary>
        /// 诗词搜索页。
        /// </summary>
        public static readonly string QueryPage = nameof(Views.QueryPage);

        /// <summary>
        /// 我的收藏页。
        /// </summary>
        public static readonly string FavoritePage = nameof(Views.FavoritePage);

        /// <summary>
        /// 数据同步页。
        /// </summary>
        public static readonly string SyncPage = nameof(Views.SyncPage);

        /// <summary>
        /// 关于页。
        /// </summary>
        public static readonly string AboutPage = nameof(Views.AboutPage);

        /// <summary>
        /// 页面键-页面类型字典。
        /// </summary>
        public static readonly ReadOnlyDictionary<string, Type>
            PageKeyTypeDictionary = new ReadOnlyDictionary<string, Type>(
                new Dictionary<string, Type> {
                    [InitializationPage] = typeof(InitializationPage),
                    [TodayPage] = typeof(TodayPage),
                    [QueryPage] = typeof(QueryPage),
                    [FavoritePage] = typeof(FavoritePage),
                    [SyncPage] = typeof(SyncPage),
                    [AboutPage] = typeof(AboutPage)
                });
    }

    /// <summary>
    /// 根导航消息。
    /// </summary>
    public class RootNavigationMessage {
        public string PageKey { get; set; }
    }

    /// <summary>
    /// 内容导航服务常量。
    /// </summary>
    public static class ContentNavigationServiceConstants {
        /// <summary>
        /// 今日推荐详情页。
        /// </summary>
        public static readonly string TodayDetailPage =
            nameof(Views.TodayDetailPage);

        /// <summary>
        /// 搜索结果页。
        /// </summary>
        public static readonly string ResultPage = nameof(Views.ResultPage);

        /// <summary>
        /// 诗词详情页。
        /// </summary>
        public static readonly string DetailPage = nameof(Views.DetailPage);

        /// <summary>
        /// 页面键-页面类型字典。
        /// </summary>
        public static readonly ReadOnlyDictionary<string, Type>
            PageKeyTypeDictionary = new ReadOnlyDictionary<string, Type>(
                new Dictionary<string, Type> {
                    [TodayDetailPage] = typeof(TodayDetailPage),
                    [ResultPage] = typeof(ResultPage),
                    [DetailPage] = typeof(DetailPage)
                });
    }

    /// <summary>
    /// 导航参数。
    /// </summary>
    public static class NavigationContext {
        /// <summary>
        /// 导航参数属性。
        /// </summary>
        public static readonly BindableProperty NavigationParameterProperty =
            BindableProperty.CreateAttached("NavigationParameter",
                typeof(object), typeof(NavigationContext), null,
                BindingMode.OneWayToSource);

        /// <summary>
        /// 设置导航参数。
        /// </summary>
        /// <param name="page">页面。</param>
        /// <param name="value">导航参数。</param>
        public static void SetParameter(BindableObject page, object value) =>
            page.SetValue(NavigationParameterProperty, value);
    }
}